[iOS] อยากจะ Force Change Orientation ของเครื่องโดยไม่ต้องพลิกเครื่องไปมาจริง ๆ

startup-photos

บ้างครั้งในการเขียนแอปพลิเคชัน มันก็มีบางเมนูทีจะต้องอยู่ใน Mode ของ Lansacpe เพื่อหาการแสดงผลที่เหมาะสม จึงเป็นที่มาของ Hint เล็ก ๆ น้อย ๆ ของบทความนี้ครับ

ผมจะขอเรียกว่า Force Change Orientation

นี้เป็น Ref ที่ผมอ่านแล้วนำมาใช้ครับ
http://stackoverflow.com/questions/26357162/how-to-force-view-controller-orientation-in-ios-8

หลัก ๆ ก็คือการเล่น Class UIDevice ตอนแรกผมนึกไม่ถึงเหมือนกันพยายามอยู่นานเลยทีเดียว
พอเห็น Code ก็บางอ๋อ เลยสามารถเอาไปเล่นได้อีกเยอะเลยครับ

Example ทุกครั้งที่มีการกดเลือก Menu ใด ๆ มันจะวิ่งเข้าที่ func adjustScreen()
เพื่อเช็คว่า CurrentController นั้นเป็น LandScreen หรือเปล่าตามด้านล่างครับ

Screen Shot 2559-09-07 at 11.15.35 AM.png

การแสดงผล HTML String บน UILabel

SONY DSC

การแสดงผล HTML String บน UILabel

บางคนอาจจะเอา UIWebView มา Display HTML String
แทน UILabel อันนี้บาปมากนะครับอย่าไปทำนะ 55555+

คือผมจะบอกแบบนี้ ในตัว UILabel มันมี NSAttributedString ให้ใช้งานครับ

แล้วตัว NSAttributedString มันก็สามารถเพิ่มคุณสมบัติต่าง ๆ ให้มากกว่า NSString ปกติครับ
เช่น String ที่มีสีติดมาด้วยเลย เป็นต้น

ในกรณีนี้เราจะสร้าง NSAttributedString ที่สามารถแสดงผลในรูปแบบ HTML String ได้ครับ
ไปดูกันเลยยยยย

-(void)configLabel:(NSString *)htmlString{

 NSError *err = nil;

 // ดูว่า HTML String ที่เราได้มาเป็น UTF-8 (NSUTF8StringEncoding) หรือ Unicode (NSUTF16StringEncoding) ก็เลือก Encoding ตาม HTML ที่เราได้รับมาครับ 
 self.titleLabel.attributedText = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF16StringEncoding] options: @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:&err];


 if (err) {
 NSLog(@"Unable to parse label text: %@", err);
 }

}

มาเขียน Swift แบบ Swift กันเถอะตอนที่ 1

 

SONY DSC
SONY DSC

“มาเขียน Swift แบบ Swift กันเถอะ”

ทำไมถึงมีประโยคด้านบน ด้วยความผมเขียนแอปฯ iOS ด้วย Objective-C ตั้งแต่แรก ๆ และยังคงนิสัยเสียเอาความเป็น Objective-C มาด้วยเมื่อเขียน Swift

เลยคิดว่า เฮ้ยยย! ปั่นมึงควรเขียน Swift ด้วย Swift Way นะ ไม่ใช่ Objective-C Way

ผมจึงจะเขียนแอปฯ BaaGames อีกครั้งด้วย Swift (วันเดียวก็เสร็จแล้วมั้ง)
แต่ผมจะค่อย ๆ เขียนและค่อย ๆ อธิบายสิ่งที่ผมคิดอยู่ในตอนที่เขียนนะครับแล้วเจอกันครับ

Let’s go!

การใช้งาน Category Class บน Objective-C

เคยเห็น Class ใน Xcode ที่มีเครื่องหมาย “+” (บวก) ไหมครับเช่น

UIImageView+AFNetworking
UIButton+AFNetworking

Class ประเภทนี้เรียกว่า Category เป็นการเพิ่ม Attribute, Method ให้กับ Object ที่เราต้องการครับ

เช่นผมต้องการเพิ่ม Default Font Style ให้กับ UILabel โดยการเรียก Method setDefaultFontStyle แน่นอนครับ ไอ้ Method setDefaultFontStyle ตัว UILabel มันไม่มีให้ใช้อยู่แล้ว ผมก็สร้าง Category ของ UILabel มาแล้วก็เพิ่ม Method นี้ลงไป

หรือผมต้องการให้ UIImageView สามารถโหลดรูปได้เองเพียงแค่ใส่ URL String เข้าไปให้มันก็พอเช่นตัวอย่างนี้ครับ
อันนี้ตัวอย่างแบบง่ายนะครับ 🙂

UIImageView+LoadImage.h

Screen Shot 2558-09-23 at 11.05.03 AM Screen Shot 2558-09-23 at 11.05.12 AM

เวลาใช้งานก็ Import Class เข้ามาก่อนครับแล้วเรียกใช้งานได้เลยแบบนี้

Screen Shot 2558-09-23 at 11.06.50 AM

สำหรับใครที่อยากได้ไฟล์นะครับ 🙂 ใช้กับโปรเจคเล็ก ๆ น้อย ๆ พอได้
แต่ถ้าโปรเจคมี Scale ที่ใหญ่ขึ้นไปใช้ของ AFNetworking เถอะครับ 5555+

ไปเลย https://github.com/zhocker/UIImageView-LoadImage

Delegate และ Delegate Method คืออะไร และเขียนอย่างไรบน Objective-C

Delegate หลาย ๆ คนที่เขียนแอปฯ บน iOS Platform คงต้องคุ้นชินกับมันมากพอสมควร และก็ต้องเคยใช้มัน อย่างน้อย ๆ ก็ของ UITextField, ไม่ก็ UITableView แล้วเราเข้าใจมันไหมแล้วมันคืออะไร? ทำไมต้องมี Delegate? Delegate Method คืออะไร

จนผมได้ไปเจอคุณ fernyb เขียนตอบไว้ที่ Stackoverflow.com

A delegate is simply a reference to another object and a delegate method is a method of the delegate.
A delegate method implements the callback mechanism which usually takes the sender as one of the parameter to be called.

Delegate เปรียบเสมือนเป็นเพียงตัวที่ใช้ Reference ไปยัง Object ใด ๆ และ Delegate Method ก็คือ Method ของ Delegate (นี้ไม่ได้กวนตีนนะ ถึงมันจะกำปั้นทุบดิ้นไปหน่อยแต่มันก็คือแบบนี้แหละ)

ผมยกตัวอย่างง่าย ๆ สักตัวแล้วกันครบผมสร้างแอปขึ้นมาสักตัวโดยแอปนี้จะไปโหลดภาพมาแล้วก็แสดงบน UIImageView (แค่นี้แหละ)
*เฮ้ย ปั่นมึงจะยกตัวอย่างง่ายไปไหม เค้าไปใช้ Category ของ AFNetworking ไม่ดีกว่าหรอ 5555555+
โดย Code ใน MainViewController ผมมีดังนี้ครับ

MainViewController.m

Screen Shot 2558-09-22 at 3.40.00 PM

Import Photo เข้ามา, ประกาศตัวแปรของ Photo และ UIImageView
และเพิ่ม Protocol PhotoDelegate เข้าไป

มีการ Init UIImageView และ Photo และมีการ set delegate ชี้ไปที่ MainViewController (ก็คือตัวมันเองนั้นแหละ)

 

และผมสร้าง Photo ขึ้นมาโดยมีรายละเอียดดังนี้ครับ

Photo.h

Screen Shot 2558-09-22 at 3.46.33 PM

ใน Photo.h ผมสร้าง Protocol ขึ้นมาชื่อว่า PhotoDelegate โดยมี Deleagte Method คือ

didiLoadImage:(NSData *)data;
Method loadImage
Object delegate

Photo.m

Screen Shot 2558-09-22 at 3.46.41 PM

ในนี้ผมสร้าง Method ขึ้นมาตัวนึงโดยทำหน้าที่โหลดรูปแบบกาก ๆ
ตรง sleep(10) ที่ผมเพิ่มเข้าไปผมต้องการสมมติว่ารูปแม่งใหญ่มาก ต้องใช้เวลาโหลดประมาณ 10 วินาทีกว่า ๆ 5555+

จะเห็นว่าตอนผมโหลดรูปผมจะเอาการทำงานลง Background Thread เพื่อให้แอปผมมันไม่ค้าง
และเมื่อทำงานเสร็จแล้วแอปมันก็จะกลับเข้ามาทำงานที่ Main Thread (หรือ UI Thread)
เพื่อส่งค่า NSData ที่ได้มานั้นกลับไปที่ MainViewController โดยใช้ Object delegate
(จำได้ไหมมันชี้ไปที่ไหนก็ MainViewController ไง)

มันก็จะไปทำงานที่ didLoadImage:(NSData *)data; ไงตัวเธอว์

นี้ไงที่ MainViewController.m

Screen Shot 2558-09-22 at 3.54.07 PM

แล้วก็นำ NSData ที่ได้มาไป Update ImageView ซะ

ที่มา –  fernyb

การตั้งค่าให้ Xcode Project Allow SSL Certificate ที่ Invalid บน iOS9

พอดีลองเล่นตัว Xcode 7 ตัว GM ดูแล้วมาลอง Run Project เก่า ๆ เท่านั้นแหละ iOS มันไม่อนุญาตให้เชื่อมต่อกับ Site ที่ SSL Certificate ที่ Invalid จ้า

วิธีแก้ปัญหาก็มี 2 วิธี
– แก้ SSL Certificate ให้ Valid ซะ (ให้มันเป็น https เป็นสีเขียว ๆ นั้นแหละครับ)
– หรือเพิ่ม Attribute เข้าไปใน Info.plist อีกนิดหน่อยครับ

ดังนี้ครับ

Screen Shot 2558-09-15 at 1.55.38 PM

เช่น

Screen Shot 2558-09-15 at 1.55.43 PM

ที่มา – twittercommunity.com

มีจอเดียวแต่อยากดู Youtube ไปด้วยเล่นเนตไปด้วยทำไงดี (Always On Top for YouTube™)

2015-07-30 12_40_45-Always On Top for YouTube™ - Chrome Web Store

สำหรับคนที่ใช้ Google Chrome นะครับ ไปโหลด Google Chrome Extension ตัวนี้มาใช้ครับ Always On Top for YouTube™

พอใช้แล้วจะเป็นแบบนี้ครับ 🙂

2015-07-30 12_45_15-New Post — WordPress.com

วิธีการใช้งานก็ใส่ Link Youtube ลงในช่อง URL YouTube แล้วกด Go!!

อยากเขียนแอปฯ ไอโฟนเรียก Web Services เขียนเองเลยไหม หรือใช้ Framework เข้าช่วย?

การเขียน iOS แอปพลิเคชันเพื่อเรียก API ต่าง ๆ ผ่าน Web Services (เน้นไปทาง Objective-C นะ) เดี๋ยวนี้มี Framework ต่าง ๆ มาช่วยมากมายครับย้อนกลับไปสมัยที่ผมอยู่ปี 4 ตอนนั้นกำลังหัดเขียนแอปไอโฟนใหม่ ๆ เลย (สมัย Non-ARC ต้อง Retain / Release ค่าของตัวแปรเอง อิอิ เขียนไม่ดี Memory Leak  กระจุย แต่ตอนนี้ set property ไม่ดีก็กิน Memory อิอิ)

สมัยก่อนก็ใช้ NSURLConnection ธรรมดานี้แหละครับ แต่ผมก็เพิ่งมารู้จัก AFNetworking หลังจากทำงานได้ประมาณ 4-5 เดือนครับ
แต่รู้การทำงาน NSURLConnection ไว้ก่อนก็ดีนะครับ ลองไปหา Example มาอ่านดูได้ครับชี้ทาง —> ที่นี้นะ

ออกตัวก่อนว่า จริง ๆ ไอ้การสอนใช้ AFNetworking ก็มีอยู่หลายที่เลยนะ ทั้งภาษาไทยภาษาอังกฤษ
แต่ที่ผมมาเขียนตรงนี้ก็คือหัดเขียน Blog ครับ มีอะไรก็แนะนำได้ครับ

เดี๋ยวผมจะยกตัวอย่างการเรียก Web Service แบบ RESTful ง่าย ๆ โดยการวิธีการ GET นะครับ
(เรียก RSS Feed จากเว็บ BaaGames.com แล้วกันนะครับ โฆษณาอิอิ)

โดยในขั้นตอนแรกต้อง Import Framework เข้าไปใน Project ก่อนครับ (จะ POD หรืออะไรก็ตามแล้วแต่ถนัดครับ)
ปล. ผมได้แอบเอา XML ไปเปลี่ยนเป็น NSDictionary 🙂

Screen Shot 2558-07-17 at 2.06.58 PM

จบแล้วครับอิอิ 🙂

Ref – AFNetworking

อยากจะ Convert XML เป็น NSDictionary จังเลย

photo-1433838552652-f9a46b332c40
ภาพประกอบไม่เกี่ยวกับเนื้อหา จาก Daniela Cuevas (https://unsplash.com/danielacuevas) รูปฟรีจ้า ไปเอามาใช้ได้สวยดี

มีหลาย ๆ ครับ ที่ผมต้องทำงานกับ Web service ที่ return message มาเป็น XML Format แล้วก็ต้องมานั่ง Parser เก็บลง Model เองซึ่งถ้าส่วนตัวผมชอบทำงานกับ Web service ที่ return message มาเป็น JSON Format มากกว่าครับเพราะมันสามารถจับยัดลงพวก Hashmap (ใน Objective-C เรียกว่า NSDictionary) ได้ก่อนเลย หลังจากนั้นจะเก็บลง Model อีกทีก็ไม่ว่ากัน

ผมก็มานั่งคิดนะว่ามันมีคนคิดเหมือนผมไหมที่ต้องการจะ Convert จาก XML มาเป็น NSDictionary

ก็เลยลองไป Search ดูด้วยคำง่าย ๆ ว่า “Convert XML to NSDictionary” ปรากฎว่าไปเจอ Link ที่อยู่บน Github ของคุณ nicklockwood เรียกว่า XMLDictionary (ชื่อเก๋มากชอบ ๆ อิอิ) เจอแบบอย่าไปรอช้าครับไป  POD มาเลย (หรือจะ Import มาตรง ๆ ก็แล้วแต่ตามสะดวกครับ แต่มันไม่ Cool อ่ะ อิอิ)
วิธีใช้ก็อยู่ในนั้นแหละหาดูลองทำดูครับไม่ยากหรอก ที่บอกแบบนี้เพราะผมไม่ได้ใช้ตัวนี้ (อ้าว! แล้วมึงจะเขียนอะไรตั้งยาว)

จริง ๆ ผมใช้ตัวนี้ครับ ใช้มานานละใช้ของคุณ amarcadet ชื่อว่า XMLReader (ตอนแรกคิดว่าเป็นพวก RSS Feed Reader อะไรเถือกนี้)
ไปเอามาใช้เลยครับ

วิธีการใช้ก็ง่ายมาก (นี่ไป Capture มาจาก Github เลยนะ หราาา ดูมึงภูมิใจมากนะปั่น)

Screen Shot 2558-07-06 at 3.28.09 PM

เอาจริง ๆ ละครับ ผมชอบใช้แบบนี้ครับScreen Shot 2558-07-06 at 3.29.01 PM

เพราะชอบ Convert จาก NSString ก่อนมากกว่าอยากเห็น Message ที่อ่านออกก่อนนะครับ อิอิ

ปล. เชคก่อนนะครับว่า XML String ที่เราได้มามัน Valid แล้ว

แถม! ถ้า Message มาเป็น JSON Format ก็จับยัดลง NSDictionary ได้เลยครับ

Screen Shot 2558-07-06 at 3.37.58 PM

ที่มา – https://github.com/nicklockwood/XMLDictionary/https://github.com/amarcadet/XMLReader

Singleton Design Pattern ของ Class ใน Objective-C

Singleton เป็น Design Pattern ประเภทหนึ่งครับ ที่จำกัดจำนวน Object (คือ 1 นั้นแหละ) ที่ถูกสร้างขึ้นมา
แต่ถ้าจะให้ผมอธิบายแบบเข้าใจง่ายขึ้นมาก็คือ
"ไม่ว่าจะประกาศตัวแปรที่เป็น Singleton Design Pattern ไว้ที่ไหนมันก็จะไปหยิบค่าจากที่เคยประกาศไว้และ และในทางกลับกันถ้ามีการเปลี่ยนแปลงค่าก็เปลี่ยนทั้งหมดครับ" (หรืองงกว่าเดิม 55555+) ไปดูตัวอย่างกันเลยครับ
คิดว่าน่าทำความเข้าใจได้ไม่ยากครับ
TNSingleton.h
@interface TNSingleton : NSObject
+ (TNSingleton *)sharedInstance;
@property (nonatomic,strong) NSString *stringYouWantShare;
@end
 
TNSingleton.m
static TPSingleton *sharedInstance;
-(id)init{
	self = [super init];
    if (self) {
              self.stringYouWantShare = @"Share this string";
    }
	return self;
}

+ (TNSingleton *)sharedInstance {
	@synchronized(self) {
        if (sharedInstance = nil){
            sharedInstance = [[TNSingleton alloc] init];
			NSLog(@"Singleton of \"%@.h Class\"",[sharedInstance class]); 
		}
    }
    return sharedInstance;
}

+(id)alloc {
    @synchronized(self) {
        NSAssert(sharedInstance == nil, @"You ever allocated a instance of singleton.");
        sharedInstance = [super alloc];
    }
    return sharedInstance;
}

เวลาเราประกาศตัวแปรก็ให้ทำดังนี้ครับ
TNSingleton *sharedTN = [TNSingleton sharedInstance]; 
// ลอง Log ค่ามาดูครับ ไปประกาศแบบนี้ไว้ที่ Class ไหนก็ได้ครับก็จะได้ค่าเดิมมาเสมอ
NSLog(@"%@",[sharedTN stringYouWantShare]);
// หลังจากนั้นลองเปลี่ยนค่าดูครับ
sharedTN.stringYouWantShare = @"Test";
แล้วก็ไป Log ค่าดูครับ!