Tuesday, March 19, 2013

วิธีเช็คเวอร์ชั่นล่าสุดของ App





หลายคนน่าจะเคยประสบกับปัญหา ที่เวลาเราอัพเดทแอพแล้ว User อาจจะไม่ได้อัพเดทตาม ซึ่งบางทีเราก็ต้องการให้อัพเดทเพื่อแก้ไขปัญหาบางอย่าง ที่เราได้ปรับแก้ไขเรียบร้อยแล้ว วันนี้ผมจะมาแนะนำการตรวจสอบเวอร์ชันของแอพ เพื่อให้ User ได้อัพเดททันที เมื่อแอพเรามีเวอร์ชั่นใหม่ล่าสุด
ส่วนวิธีการทำนั้นสามารถทำได้หลายวิธี ยกตัวอย่าง (ที่คิดออกตอนนี้นะ)
1. ใช้ Server ส่วนตัว แล้วให้แอพ Request ทุกครั้งก่อนใช้งาน เพื่อตรวจสอบเวอร์ชั่นล่าสุด ถ้าไม่ใช่ล่าสุด ก็ให้ขึ้น Alert เพื่ออัพเดทก่อนใช้งาน
2. ไม่ต้องมี Server ส่วนตัวให้วุ่นวาย ใช้วิธีการ Request ไปที่ iTunes แทน เพื่อดูเวอร์ชั่นล่าสุดของแอพเราที่อยู่บน App Store ถ้าไม่ใช่ล่าสุด ก็ให้ขึ้น Alert เพื่ออัพเดทก่อนใช้งาน

โดยวิธีที่ผมจะแนะนำวันนี้คือแบบที่ 2
สิ่งที่เราต้องเตรียมคือ
1.App ID ของแอพที่เราต้องการตรวจสอบ
ดูง่ายๆ จาก https://itunes.apple.com/th/app/thai-tunes-tv-free/id454349366
App ID = 454349366

2. เนื่องข้อมูลที่ใช้เราจะได้กลับมาเป็น JSON ก็ต้องใช้ Lib กันหน่อย :) ที่ผมใช้ประจำก็ SBJson

พร้อมแล้วก็สร้าง Xcode Project กันขึ้นมาเลยครับ โดยการใช้งานจะตรวจสอบทุกครั้งเมื่อเปิดแอพ ให้
เรานำ คำสั่งที่จะตรวจสอบเวอร์ชั่นไว้ใน Method นี้

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

}


เอาจริงๆอยากทำเป็น Tutorial นะ แต่ด้วยข้อจำกัดด้านเวลา เด๋วถ้าเริ่มว่างๆหน่อย จะพยายามเขียนให้ได้นะครับ รอบบนี้เอาแบบ อธิบายยาวเลยนะ ^^'

โอเคจากนั้นเราก็ทำการตรวจสอบเวอร์ชั่นละ จาก API นี้


http://itunes.apple.com/lookup?id=AppID

ตรง AppID เราก็นำ App ID ของเราใส่ลงไป ถ้าลองนำไปวางบน Browser ก็จะมีข้อมูลออกมาเพียบ ดูแล้วงงมาก แต่ถ้าใครอยากดูข้อมูลแบบง่ายๆ ก็ลองใช้พวก JSONView ดูก็ได้ครับ

ในส่วนของโค้ด ก็จะเป็นแบบนี้

NSData * data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[NSString stringWithFormat:@"http://itunes.apple.com/lookup?id=%@",Your_App_ID] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
    
    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    if ([[[jsonString JSONValue] objectForKey:@"resultCount"] integerValue] == 1) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"%@",[[jsonString JSONValue] objectForKey:@"results"]);
            
            NSArray *resultArray = [[jsonString JSONValue] objectForKey:@"results"];
            
            float latestVersion = [[[resultArray objectAtIndex:0] objectForKey:@"version"] floatValue];
            float appVersion = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] floatValue];
            
            if (appVersion < latestVersion) {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"คุณกำลังใช้ %@ เวอร์ชั่นเก่า",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]] message:@"เพื่อใช้งานคุณสมบัติใหม่ คุณจำเป็นต้องอัพเดทเวอร์ชั่นล่าสุดในตอนนี้" delegate:self cancelButtonTitle:@"ปิด" otherButtonTitles:@"อัพเดท",nil];
                [alert show];
                [alert release];
            }
        });
    }
    
    [data release];


ในส่วนแรกจะทำการ Request ไปที่ iTunes ถ้าไม่มีอะไรผิดพลาด API จะ Return ข้อมูลมาเป็น 1 จากนั้นก็ทำการเปรียบเทียบ App Version กับ iTunes Version ดู ถ้า App Version น้อยกว่า iTunes Version ก็ Alert ให้อัพเดท แต่ถ้าเท่ากันแล้วก็ผ่าน แบบนี้ครับ

ผมแนบตัวอย่าง Souce Code ไว้ด้วย ใครอยากลองดาวโหลดไปเล่นดูก็ตามสบายนะครับ อธิบายอาจจะงงๆ หน่อยนะ ไว้มีโอกาสจะมีเขียนเป็น Tutorial ดีๆ ไปละครับ :)















Monday, December 24, 2012

การออกแบบ Icon


บทความนี้เกิดจากผมต้องการหาข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบ App Icon ขึ้นมา สำหรับการส่ง App ขึ้นไปยัง Apple Store นั้นจะต้องเตรียมรูปเบื้องต้น 5 รูป* ก็ถือว่าใช้ได้แล้ว คือ
1. รูปขนาด 1,024 x 1,024 pixel สำหรับ App Store
2. รูปสำหรับ iPhone
- iPhone 2G, 3G , 3GS ขนาด 57 x 57 pixel
- iPhone 4, 4S, 5 ขนาด 114 x 114 pixel (2 เท่าจากแบบเดิม)
3. รูปสำหรับ iPad
- iPad 1, 2 , mini ขนาด 72 x 72 pixel
- iPad 3, 4 ขนาด 144 x 144 pixel (2 เท่าจากแบบเดิม)

เท่านี้ก็ครบละ แต่สิ่งที่ผมต้องการรู้เพิ่มเติมก็คือ มุมขอบของ Icon หรือที่เรียก Corner Radius นั้นแต่ละแบบมีขนาดเท่าใด เพราะในการออกแบบ Icon ให้สวย จะต้องตัดรูปให้พอดีกับมุมที่จะถูกย่อลงโดยอัตโนมัติ จึงได้ข้อสรุปว่าให้คำนวณแบบนี้

เนื่องจาก Apple ใช้ Icon เร่ิมแรกตอนเปิดตัว iPhone เป็นขนาด 57 x 57 pixel และมี Radius เป็น 10
ดังนั้นหากต้องการหาค่า Radius ขนาดอื่นๆ ก็จะใช้วิธีคำนวณแบบนี้

Radius = (10/57) x New Size

เช่น หาค่า Radius ของ Icon ขนาด 114 x 114 pixel

Radius = (10/57) x 114 = 20

ดังนั้น ค่า Radius ของ Icon ขนาด 114 x 114 ก็คือ 20 ครับ ผมขอทำสรุปค่า Radius สำหรับ Icon ขนาดต่างๆ อีกครั้งก็จะได้


1. 1,024 x 1,024 = 179.64
2. 57 x 57 = 10
3. 114 x 114 = 20
4. 72 x 72 = 12.63
5. 144 x 144 = 25.26


* ยังมี Icon อื่นๆ อีกนอกเหนือจากนี้ เช่น Icon Spotlight , Setting เป็นต้น ที่ผู้เขียนยังไม่ได้กล่าวถึง แต่สามารถใช้แค่รูปเบื้องต้น 5 รูปนี้ก็ถือว่าเพียงพอแล้ว

ที่มา Hicks Design

Wednesday, October 24, 2012

แก้ปัญหา Auto Rotate on iOS6

สำหรับ iOS6 SDK นั้นมีคำสั่งหลายตัวเริ่ม Deprecated ไปเหมือนกัน อย่างวันนี้จะเขียนเรื่องของ Autorotate บน iOS6 โดยใน iOS รุ่นต่ำกว่านี้เวลาที่เราต้องการสั่งให้เครื่องตั้งหรือนอน เราจะใช้คำสั่ง

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
}

แต่พอเป็น iOS6 คำสั่งนี้ได้ถูกยกเลิกไป แล้วเพิ่ม 2 คำสั่งนี้เข้ามาแทน

- (NSUInteger)supportedInterfaceOrientations
{
}

- (BOOL)shouldAutorotate
{ 
}

ดังนั้นสิ่งที่ผมจัดการกับปัญหานี้คือสร้าง Category ของ UINavigationController ขึ้นมาแล้วใน ViewController เราก็เรียกใช้คำสั่งเหล่านี้ได้เลย เช่นผมมีคลาส ViewController อยู่หนึ่งตัวก็จะเรียกใช้แบบนี้ได้เลย ตัวแรกจะใช้งานสำหรับ iOS 5 ลงไป

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

ส่วน 2 ตัวนี้จะใช้สำหรับ iOS 6 ขึ้นไปครับ

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

- (BOOL)shouldAutorotate
{
    return YES;
}

สำหรับ Category นี้ผมเขียนไว้แล้วลอง ดาวโหลด ไปใช้งานกันได้เลยครับ :D


Sunday, October 21, 2012

เลือกติด iAd หรือ AdMob ดี








ในช่วงสมัยที่ Steve Jobs ยังอยู่ที่ Apple (อย่าถามนะครับว่าตอนนี้เขาหายไปไหน ^^) ถ้าจำไม่ผิด Apple iAd น่าจะอยู่ในช่วงการเปิดตัว iOS 4 ซึ่งช่วงนั้น Mobile Ads กำลังเริ่มได้รับความนิยมมากขึ้นเรื่อยๆ ผู้เล่นที่โดดเด่นที่สุดก็คงหนีไม่พ้นเจ้าพ่อยักษ์ใหญ่แห่งวงการโฆษณา Google AdMob นั้นเองครับข้อดีของ AdMob นั้นมีเยอะกว่า iAd มากเนื่องจากเป็น Ads ที่ Cross-Platform พูดง่ายๆคือมันสามารถไปแสดงผลได้หลาย OS เช่น Android, iOS, Windows Phone เป็นต้น จึงทำให้นักพัฒนาส่วนมากเลือกที่จะใช้ AdMob เป็นหลัก จากที่ลองหาข้อมูลดูและประสบการณ์ส่วนตัว (บ้าง) ขอแชร์ข้อมูลเพื่อประกอบการตัดสินใจของใครที่กำลังจะทำแอพฟรีแล้วติด Ads เป็นรายได้เป็นหลักครับ จากสถิติที่พอจะสรุปมาได้จะเป็นดังนี้

Apple iAd
eCPM - $1 - $5
Country - U.S., Canada, U.K., Germany, Italy, Spain, France, and Japan
Impression - 20 %

Google AdMob
eCPM - $0.01 - $1 (ส่วนมาก $0.01)
Country - ทั่วโลก
Impression - 90%

Earning ที่เราจะได้รับ ไม่คิดจากว่าคนที่ใช้งานแอพของเรา Click Ads กี่ครั้งแต่คิดจาก (Impression / 1000) x eCPM

ยกตัวอย่างเช่น ในหนึ่งวันมีคนใช้งานแอพของเราและมีการแสดงผลของโฆษณา (Impression) 20,000 ครั้ง ก็จะคำนวณได้เป็น

Earning = (20,000 / 1,000) x eCPM

iAd
Earning = 20 x $1
Earning = $20

AdMob
Earning = 20 x $0.01
Earning = $0.2 ใช่แล้วครับแค่ 2 Cent (ฮา)

ผมรู้ว่าทุกคนกำลังคิดอะไรอยู่ ก็เห็นๆอยู่แล้วว่า iAd มันเมพซ่ะขนาดนั้นจริงไหมละครับ แต่ความจริงอันน่าโหดร้ายสำหรับคนไทยเราก็คือ iAd มันแสดงผลแค่ 8 ประเทศเอง แถม Impression แค่ 20% พูดง่ายๆคือ Ads มันไม่ค่อยแสดง แต่เทียบกับ AdMob แล้ว 90% ขึ้นแถมยังแสดง Ads ได้ทั่วโลกอีก ผมยกตัวอย่างให้เห็นภาพใหม่อีกครั้งแล้วกันครับ จากตัวอย่างเดิม 20,000 แต่ความจริงจะเป็นเช่นนี้

AdMob
Earning = ((20,000 x 90) / 100) / 1,000) x eCPM
Earning = (18,000 / 1,000) x 0.01
Earning = 18 x $0.01
Earning = $0.18

iAd
Earning = ((20,000 x 20) / 100) / 1,000) x eCPM
Earning = (4,000 / 1,000) x 0.01
Earning = 4 x $1
Earning = $4

จะเห็นว่า iAd ยังไงมันก็คงยังคงเป็นทางเลือกที่ดีที่สุดหากเราพัฒนาแอพบน iOS แต่สิ่งที่สำคัญที่ต้องใช้ประกอบการตัดสินใจของนักพัฒนาอีกอย่างคือ กลุ่มเป้าหมายของผู้ใช้งานแอพของเรา ถ้าเราทำแอพสำหรับคนไทย แน่นอนต้องติด AdMob ซึ่งจะดีกว่า ถึงแม้จะมีคนไทยทีอยู่ต่างประเทศด้วยก็เหอะ แต่มีปริมาณน้อยมาก เมื่อเทียบกับผู้ใช้ในไทย ในขณะเดียวกันถ้าเราทำแอพที่ให้ผู้ใช้สำหรับ 8 ประเทศที่ iAd รองรับ เราก็ควรติด iAd จะดีที่สุดครับ แต่ผมก็ได้แต่หวังว่าในอนาคตอันใกล้นี้ Apple จะเปิดบริการ iAd ให้รองรับได้ทั่วโลก นักพัฒนาอย่างเราๆ จะได้มีรายได้เพิ่มขึ้นกันบ้างไม่มากก็น้อยครับ

ก็หวังว่าบทความนี้จะเป็นตัวที่ช่วยในการประกอบการติดสินใจติด Ads ของแต่ละท่านได้นะครับ

*หมายเหตุ ในปัจจุบันผู้ให้บริการ Mobile Ad Network มีประมาณเยอะขึ้นเรื่อยๆ นี่เป็นเพียงตัวอย่างของผู้ให้บริการ 2 รายเท่านั้น อาจจะมีผู้ให้บริการรายอื่นๆ ที่ให้รายได้เยอะกว่านี้ซึ่งผู้เขียนไม่ได้ หาข้อมูลไว้ ส่วนตัวเลขต่างๆ ทั้ง eCPM , Impression ในการคำนวณนั้นมาจากข้อมูลที่ค้นหาบน Internet และประสบการณ์ส่วนตัว (บ้าง) เท่านั้น ซึ่งในความเป็นจริงตัวเลขเหล่านี้มีการเปลี่ยนแปลงโดยตลอด จะมากจะน้อยขึ้นอยู่กับผู้ให้บริการ Ad Network เหล่านั้นครับ

Saturday, October 20, 2012

วิธีเช็คว่าหน้าจอขนาด 4" หรือ 3.5"

หลังจากที่ Apple เปิดตัว iPhone 5 ไปเมื่อวันที่ 12 กันยายน 2555 ทำให้เกิดปัญหาขึ้นกับนักพัฒนา iOS บ้างเหมือนกัน นั้นคือหน้าจอของ iPhone มีขนาดไม่เท่ากัน จาก iPhone รุ่นแรกจนถึง iPhone 4S จะมีหน้าจอขนาด 3.5"(320x480) ส่วน iPhone 5 นั้นจะมีขนาดหน้าจอ 4" (320x568) ซึ่งยาวขึ้นกว่าเดิม ดังนั้นในการพัฒนาเราจำเป็นจะต้องคำนวณว่าเครื่องที่ใช้งานแอพของเราอยู่นั้นมีขนาดหน้าจอเป็นเท่าไร เพื่อจะได้แสดงผลการทำงานได้อย่างถูกต้อง จริงๆอาจจะมีวิธีอื่นๆนอกเหนือจากนี้ แต่ผมขอใช้เทคนิคง่ายๆ คือการเช็ค screen bounds ถ้ามีความสูงเท่ากับ 568 ก็ต้องเป็นหน้าจอขนาด 4" แน่ๆ แต่ถ้าไม่ใช่ก็เป็น 3.5" เดี๋ยวเรามาดูคำสั่งกันเลยครับ

            CGRect screenBounds = [[UIScreen mainScreen] bounds];
            if(screenBounds.size.height == 568) {
                NSLog(@"4 inch");
            }else {
                NSLog(@"3.5 inch");
            }

Monday, October 8, 2012

UISteper

ต่อจากเรื่องของ UIRefreshControl วันนี้ขอนำเสนออีกหนึ่ง Control ซึ่งจะเพิ่มเข้ามาตั้งแต่ iOS เวอร์ชั่น 5.0 ขึ้นไป เจ้าตัวนี้มีชื่อว่า UIStepper ครับ


UIStepper เป็น Control ที่ใช้ในการนับจำนวนไม่ว่าจะเพิ่มหรือลดก็ตามแต่ หากเราสร้างโปรแกรมที่ต้องการนับจำนวน เช่น จำนวนผู้เข้าห้องพักในโรงแรม เป็นต้น
มาดูการใช้งานกันได้ครับ
สำหรับโปรเจคนี้ผมสร้างโดยการเชื่อม UI กับ Code เลย (ง่ายมากๆ ^^) ไว้เป็นหัวข้อต่อไปจะมาแนะนำการใช้งานอีกทีครับ



การทำงานของโปรเจคนี้คือ User จะกดที่ Stepper แล้วพิมพ์แสดงตัวเลขที่กดออกมาที่หน้าจอครับ โดยที่ผมจะกำหนดค่าต่างๆไว้ใน ViewDidLoad มาดูกันเลย

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Set Max Value
    self.stepper.maximumValue = 10.0;
    // Set Min Value
    self.stepper.minimumValue = 0.0;
    // Set Step Value
    self.stepper.stepValue = 1.0;
}


จากโค้ดผมกำหนดค่่า Maximum และ Minimum ของ Stepper ให้เป็น 0 - 10 นะครับ จากนั้นกำหนดค่า Step Value ในการกดเป็นเพิ่มหรือลดทีละ 1 ค่า


และสร้าง Method ขึ้นมาหนึ่งตัวคือ pressStepper สำหรับ Method นี้จะทำหน้าที่ในการแสดงผลของตัวเลขที่กดออกมาทางหน้าจอผ่าน UILabel ครับ


- (IBAction)pressStepper:(id)sender {
    [self.stepperLbl setText:[NSString stringWithFormat:@"%.1f",self.stepper.value]];
}


สำหรับการใช้งาน UIStepper เบื้องต้นก็มีประมาณนี้ครับ ส่วนใครที่อาจจะยังงงๆ อยู่สามารถดาวโหลดตัวอย่าง Souce ไปดูได้ครับ

Sunday, October 7, 2012

UIRefresh Control

บทเริ่มแรกขอแนะนำเกี่ยวกับความสามารถใหม่บน iOS6 กันดีกว่านะครับ กำลังมันส์มือ ^^ สำหรับใครที่อัพเดท iOS เป็นเวอร์ชัน 6 ไปเป็นที่เรียบร้อยน่าจะเห็น Pull to Refresh ตัวหนึ่งที่อยู่ใน Mail App นะครับ หน้าตามันจะเป็นแบบดังภาพนี้เลย


คงจะอ๋อกันแล้วนะครับ สำหรับ Refresh ตัวนี้ โดยความสามารถ Apple ได้เปิดให้นักพัฒนาสามารถใช้งานได้เหมือนกันแต่ต้องเป็น iOS6 ขึ้นไปนะครับถึงจะใช้ได้
สำหรับ Control ตัวนี้มีชื่อว่า UIRefreshControl หากใครใช้ XCode 4.5 ขึ้นไป ก็ลองเล่นดูกันได้ครับ 

เริ่มต้นผมสร้าง Object ของ UIRefreshControl ขึ้นมาแล้วเพิ่มเข้าไปเป็น Subview ของ UITableView ต้องเป็น UITableView เท่านั้นนะครับ


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    refreshControl = [[UIRefreshControl alloc] init];
    [refreshControl addTarget:self action:@selector(pullRefresh) forControlEvents:UIControlEventValueChanged];

    [self.tableView addSubview:refreshControl];
}


จากนั้นถ้าเร่ิมมีการ Pull ผมจะให้โปรแกรมเข้าไปทำงานในส่วนของ Method -(void) pullRefresh แล้วส่ัง หยุดการ Refresh หากใครที่นำไปประยุคใช้ก็ให้มาทำคำสั่งที่เราต้องการใน Method นี้ได้เลยครับ เช่น สั่งโหลดข้อมูลล่าสุด แล้ว Reload TableView เป็นต้นครับ

- (void) pullRefresh {
    [refreshControl endRefreshing];
}

สำหรับ RefreshControl ก็มีเท่านี้ครับ ง่ายใช่ไหมละ ลองฝึกใช้กันนะครับ เดี๋ยวก็คล่องแล้ว ส่วนใครอยากลองดาวโหลด Source ไปเล่นดูก็ จิ้มได้เลยครับ