2011年9月16日

[iPhone]Push Notification機制


Push Notification機制,可以讓Server來通知有安裝軟體的device,讓有安裝app的使用者可以收到server傳來的訊息。

1.      設定Server上的Notification功能:
(1)   先到iPhone Dev Center網站選取appID並將Enable for Apple Push Notification service打勾並點選Configure,點選之後會出現產生SSL憑證的視窗。
(2)   接下來打開Mac裡面的Keychain Access程式(鑰匙圈存取),打開最上面工具列的Keychain Access(鑰匙圈存取)>Certificate Assistant(憑證輔助程式)>Request a Certificate from a Certificate Authority(從憑證授權要求憑證),填寫CA相關的資訊之後點選繼續,並選擇存放的位置之後點選完成
(3)   接下來回來原本的網頁上,點選Continue,選擇剛剛步驟(2)產生的CSR檔點選產生,等待產生完成之後,就把檔案下載回來安裝到伺服器中。

2.      Client端程式碼:

Push Notification功能的程式再啟動的時候,就會對iPhone進行Notification功能的註冊,包含了AlertBadge numberSound三種。
Alert會在iPhone上出現提示視窗,Badge number是在app icon的右上角顯示數字,Sound則是發出聲音。

我們可以在applicationFinishLauchingWithOptions:裡面加上

[[UIApplcation sharedApplication] registerForRemoteNotificationTypes :
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound];

這樣就是對Alert Badge numberSound進行註冊。

這一段code執行成功會呼叫application:didRegesterForRemoteNotificationsWithDeviceToken:
我們可以透過第二個參數得到device token,接下來要將這個device token傳給server

3.      Server傳送的格式
每一次Push Notification能夠帶payloadpayload的最大長度規定是256 bytes
並且必須帶有key”aps”dictionary

Aps dictionary
Key
Type

alert
String dictionary
可以指定要showmessage,或是傳送一個dictionary進行進階的設定
Alert dictionary
key
Type

body
string
Alert message
action-loc-key
String / null
如果指定string,原本的View button會替換成指定的string
如果指定為nullalert視窗就只會出現單一一個OK button
loc-key
string
指定顯示格式(必須儲存在Localizable.strings)
loc-args
Array of string
指定顯示字串的變數陣列
launch-image
string
指定app lunch起來的時候會顯示的畫面。

badge
Number
顯示Application icon右上角紅色的數字,傳送0,圓圈就會消失
sound
String
接收到notification的時候的聲音檔案名稱。

JSON範例
Alert message顯示Test MessageIcon右上角數字顯示3,並播放bingbiong.aiff音效。
{
  "aps":
{
 "alert":"Test Message",
"badge":3,
"sound":"bingbiong.aiff"
}
}

Alert message顯示Test Message,並播放bingbiong.aiff音效,badge不傳送則數字會消失。
{
  "aps":
{
 "alert":"Test Message",
"sound":"bingbiong.aiff"
}
}



2011年8月4日

[C++學習筆記]Appearance屬性

Control 類別的屬性
Appearance


BackColor
Control物件的背景顏色
BackGradientStyle
背景漸層的方向,可以設定BackColorBackSecondaryColor為漸層的兩種色彩
BackgroundImageLayout
背景圖片的樣式,設定BackImage時才有效
BackHatchStyle
BackColor作為底,BackSecondaryColor為線,可以選擇不同的BackHatchStyle繪製不同的線條樣式作為背景
BackImage
設定背景圖片
BackImageAlignment
背景圖片的對齊方式
BackImageTransparentColor
指定某個顏色,背景圖片中的這個顏色會變成透明的
BackImageWrapMode
指定背景圖片的排版方式
BackSecondaryColor
指定次要被景色
BoderlineColor
指定邊框的顏色
BoderlineDashStyle
指定邊框的樣式
BoderlineWidth
指定邊框的寬度
BorderSkin
這個項目內,可以指定邊框的樣式
Cursor
可以指定一種滑鼠指標的樣式
當滑鼠移到這個物件上方的時候,滑鼠指標會變成指定的樣式
Palette
指定圖表內容中的顏色
PaletteCustomColors
可選擇多個顏色自行建造新的Palette
RightToLeft
RightToLeft 屬性是用於語言由右至左書寫 (例如希伯萊文或阿拉伯文) 的國際性應用程式。這個屬性設定為 RightToLeft.Yes 時,包含文字的控制項項目會由右至左顯示。
Text

UseWaitCursor
指定是否要使用等待的游標

2011年8月2日

[iPhone]浮點數比較

今天發現了一個奇怪的問題,
我把一個icon的alpha值拿來比較,圖的alpha值是1.0,

我做了這樣的比較,但傳回的都是NO,
icon.alpha == 1.0

後來發現寫1.0還不夠,要寫1.0f才行...
像這樣

icon.alpha == 1.0f

2011年7月6日

[iPhone] cell的選中樣式


要怎麼設定cell的被選中樣式呢?
在default的設定中,cell被選中會呈現藍色,
就像這樣:


UITableViewCell中有一個屬性叫做selectionStyle可以指定這個cell被選中要呈現哪一種樣式,


如果我們指定:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
就會長這樣:


如果我門指定:
cell.selectionStyle = UITableViewCellSelectionStyleGray;
就會長這樣:



2011年4月28日

[iPhone]Object的擁有權與配置


Object Ownership Policy

每一個物件(object)會有一個或多個的擁有者(owner)。只要物件有擁有者(owner),這個物件就不會消失;若物件沒有擁有者,系統會自行銷毀(destroy)這個物件。

創建即擁有
當你使用alloc, new, copy, mutableCopy時,就代表你創建(create)一個物件(object),也就擁有物件(object)的擁有權
使用retain就能獲得物件的擁有權
一個物件可以擁有一個以上的擁有者。如果你希望一個物件繼續存在,可以使用retain獲得擁有權,讓物件繼續存在。
使用結束須放棄擁有權
可以送出"release"或"autorelease"訊息來放棄擁有權
不能放棄非自身擁有的物件

 


 

Retain Counts

每個物件都可以呼叫"retain count"來計算目前的擁有者數量

當你創建一個物件時,物件的retain count為1

當傳送retain 給物件,retain count會增加1

當傳送release給物件,retain count會減1

當傳送autorelease給物件,代表未來retain count將會減少1

當物件的retain count減少至0的時候,物件就會被dealloc

Autorelease

Autorelease是在NSObject中定義的。送出autorelease訊息,代表你在未來會放棄對物件的擁有權。

可以採用下面這個例子來實做:

– (NSArray *)sprockets

{

NSArray *array = [[NSArray alloc] initWithObjects:mainSprocket,auxiliarySprocket, nil];

return [array autorelease];

}

在這個例子中使用了alloc,因此我們擁有了array的擁有權,並且有「放棄擁有權」的責任。這時候我們就可以使用autorelease。


 

也可以以下面的方式來實做這個function:

– (NSArray *)sprockets

{

NSArray *array = [NSArray arrayWithObjects:mainSprocket,auxiliarySprocket, nil];

return array;

}

這個例子中,我們並沒有得到array的擁有權,因此我們不需要放棄擁有權。


 

Validity of Shared Objects

接收的物件可以在整個function的scope中使用,也可以在此function中回傳這個接受到的物件,且不需擔心物件被release掉。

以下有兩個例外的例子:

1. 把物件從collection中移除

heisenObject = [array objectAtIndex:n];
[array removeObjectAtIndex:n];
// heisenObject could now be invalid.
當一個物件從collection移除的時候,會送出一個release訊息。如果這個collection是物件唯一的擁有者,物件就會被dealloc

2. 當"parent object" 被dealloc

id parent = <#create a parent object#>;
... //
heisenObject = [parent child] ;
[parent release]; // Or, for example: self.parent = nil;
// heisenObject could now be invalid.
當我們release外層的物件,且外層物件是內層物件的唯一擁有者,那內層物件會和外層物件一起被dealloc


 

Accessor Methods

如果你的class中有一個物件變數,你必須確定他不會在你使用的時候被release掉。

當物件被設定的時候,你必須得到這個物件的擁有權,也必須在使用完後放棄擁有權。


 

Deallocating an Object

當retain count為0的時候,物件就會被dealloc,dealloc method會自動的被呼叫。

Dealloc method的目的是把object所擁有的記憶體釋放掉。


 

如果你的class裡面有實例變數,你就必須實做dealloc 方法將這些實例變數release掉,並呼叫父類別的dealloc。

舉例來說,如果我們有兩個實例變數: mainSprocket 和 auxiliarySprocket 。就必須像下面這樣,實做dealloc。

- (void)dealloc {

[mainSprocket release];

[auxiliarySprocket release];

[super dealloc];

}


 

Objects Returned by Reference

有些在Coca定義的object會以位址傳回。

有些method會使用NSError來包含錯誤資訊,像是:

● initWithContentsOfURL:options:error: (NSData)

● initWithContentsOfFile:encoding:error: (NSString)

● executeFetchRequest:error: (NSManagedObjectContext)

如果我們呼叫這些方法,我們並沒有創建NSError物件,所以我們並沒有擁有權,也不需要去release他。

NSString *fileName = <#Get a file name#>;
NSError *error = nil;
NSString *string = [[NSString alloc] initWithContentsOfFile:fileName
encoding:NSUTF8StringEncoding error:&error];
if (string == nil) {
// deal with error ...
{
... //
[string release];

 

Retain Cycles

在某些情況下,兩個object有可能會有循環參照的情形。
舉例來說,考慮一個文字程式的物件關係:
一個Documet object會創建document中的每一頁(Page Object),每一個Page object會有一個實例變數來儲存Page Object是屬於哪一個document object。若Document object retain 了Page object而且Page object也retain 了Document object,到page object release之前 Document object的retain count 不會為0,且Page object也不會被release掉,除非Document被dealloc。
解決方法是,父親物件retain子物件,但是子物件不retain父親物件。

Weak References to Objects

當我們retain一個object時,會產生"強"參考。一個物件擁有強參考是不會被release掉的,強參考決定了一個object的壽命。

在某些情況下,你可能不希望物件不自動dealloc,這時候可以使用"弱"參考。使用pointer來儲存物件產生弱參考。

弱參考可以應用循環參照上。舉例來說,object A和B互相溝通,A和B都需要一個對方的參照,如果A和B互相都retain對方,那麼A和B都不會被dealloc。要打破這種循環參照的方式,其中的一個object必須是另一個object的子object並以弱參考連結另一個object。

以實際的例子來說,在一個階層式的view中, 一個parent view擁有他的child view,但child view並不擁有他的parent,而child view仍然需要知道他的parent view是誰,因此在child內保留一個弱參考到他的parent。
假設有一個物件,你只擁有了一個弱參考指向這個物件,傳送訊息給物件的時候就必須注意。如果你傳送了一個訊息給已經dealloc的物件,應用程式就會crash。你必須明確的定義物件什麼時候有效。

2011年4月20日

[iPhone]讓tabBarController內的viewController回到第一頁


- (void)tabBarController:(UITabBarController *)_tabBarController didSelectViewController:(UIViewController *)viewController 
{
   //取得user點選的Tab index
   NSInteger indexofTab = [_tabBarController.viewControllersindexOfObject:viewController];
   
   if (indexofTab >= 4) //若是Tab大於等於4表示為more button
   {
      [_tabBarController.moreNavigationControllerpopToRootViewControllerAnimated:NO];//讓more回到第一頁
   }
   if ([viewController isKindOfClass:[UINavigationControllerclass]]) //讓navController回到第一頁
   {
      [(UINavigationController*)viewController popToRootViewControllerAnimated:NO];
   }
}

2011年1月31日

[iPhone]NSDate和NSString的互相轉換

NSDate轉換為NSString

NSDateFormatter *date_formatter = [[[NSDateFormatter alloc]init] autorelease];
[date_formatter setDateFormat:@"YYYY/MM/dd hh:mm"];
NSString *date = [[date_formatter stringFromDate:[NSDate date]]];


NSString轉換為NSDate

NSDateFormatter *date_formatter = [[[NSDateFormatter alloc]init] autorelease];
[date_formatter setDateFormat:@"YYYY/MM/dd hh:mm"];
NSDate *date = [date_formatter dateFromString:@"2010/01/01 12:12"];

[iPhone]亂數產生NSDate物件

產生2時間內的NSDate

給定兩個NSDate物件開始日期beginDate、結束日期endDate


srandom(time(NULL));//setting random seed
NSTimeInterval interval = [endDate timeIntervalSinceDate:beginDate];
NSTimeInterval randomInterval = random()% (int)interval;
NSDate *currentDate = [beginDate dateByAddingTimeInterval:randomInterval];

給定一指定日期currentDate,產生該時間之前或之後的隨機NSDate物件
srandom(time(NULL));//setting random seed
NSTimeInterval interval = 60*60*24;//設定時間間隔的最大秒數
NSTimeInterval randomInterval = random()% (int)interval;
NSDate *randomDate = [currentDate dateByAddingTimeInterval:randomInterval];//產生currentDate之後的隨機時間

如果要產生currentDate之前的隨機時間,可以把
randomInterval加上負號,就可以產生之前的時間了。