在app運行的情況下接收推送信息

更多 在app運行的情況下接收推送信息

當你的iPhone收到推送信息後到底會發生什麼呢?總共有三種可能性:

  • app在前臺運行. 接收到推送信息時屏幕上不會有任何顯示,也不會有提示音,但你的app delegate會收到這個推送信息。你可以在這裏加入代碼來處理接收到的信息。
  • app不在前臺運行。iPhone可能停留在主界面或者另一個app正在運行.一個提示窗口會彈出,可能伴隨着提示音。用戶可以點擊Close按鈕來關閉這個窗口或者點擊View按鈕來打開你的app。如果用戶點擊的時Close按鈕,那你的app不會處理這個推送的信息。
  • iPhone在鎖屏狀態下. 同樣一個提示窗口彈出,並伴隨着提示音,但是這個窗口不會有Close和View按鈕。屏幕解鎖後會自動進入你的app。

因爲app delegate是接收推送信息的地方,我們對app的最後改動都是在AppDelegate.m文件中。我們需要修改兩處:

  1. application:didFinishLaunchingWithOptions:函數. 如果推送信息到達時你的app不在前臺運行,而用戶在彈出窗口點擊了“View”按鈕,你的app會重新運行然後這個信息會作爲參數注入到application:didFinishLaunchingWithOptions:函數中。
  2. application:didReceiveRemoteNotification:函數. 如果信息到達時你的app正在前臺運行,那這個函數就會被調用。在iOS4.0或更新的版本,如果你的app從暫停狀態進入前臺,這個函數也會被調用。你可以用UIApplication的applicationState屬性來檢查你的app是否是從暫停狀態甦醒。

上述的兩個函數都會有一個字典參數其中包含了JSON格式的推送信息內容。OS已經幫我們把JSON格式的信息轉換成Objective-C字典了。將下面的代碼加到didFinishLaunchingWithOptions:函數的return語句前:

 
if (launchOptions != nil)
	{
		NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
		if (dictionary != nil)
		{
			NSLog(@"Launched from push notification: %@", dictionary);
			[self addMessageFromRemoteNotification:dictionary updateUI:NO];
		}
	}

 

我們先確保launchOptions參數不是nil以及launchOptions中包含了推送信息。然後調用addMessageFromRemoteNotification函數來處理這個信息。

把下面的函數加到AppDelegate.m文件中:

  - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
  {
  	NSLog(@"Received notification: %@", userInfo);
	[self addMessageFromRemoteNotification:userInfo updateUI:YES];
  }

這個函數同樣依靠addMessageFromRemoteNotification來完成處理信息的工作。
將下面這個函數複製粘貼到didFinishLaunchingWithOptions:函數上面:

- (void)addMessageFromRemoteNotification:(NSDictionary*)userInfo updateUI:(BOOL)updateUI
{
	Message* message = [[Message alloc] init];
	message.date = [NSDate date];
 
	NSString* alertValue = [[userInfo valueForKey:@"aps"] valueForKey:@"alert"];
 
	NSMutableArray* parts = [NSMutableArray arrayWithArray:[alertValue componentsSeparatedByString:@": "]];
	message.senderName = [parts objectAtIndex:0];
	[parts removeObjectAtIndex:0];
	message.text = [parts componentsJoinedByString:@": "];
 
	int index = [dataModel addMessage:message];
 
	if (updateUI)
		[self.chatViewController didSaveMessage:message atIndex:index];
 
	[message release];
}

我保證這是最後一點代碼了。然我們解釋一下這段代碼。

Message* message = [[Message alloc] init];
	message.date = [NSDate date];

首先我們創建一個Message對象。我們會把推送信息的內容提取出來,填入到這個對象中然後將這個對象加入到DataModel中。

	NSString* alertValue = [[userInfo valueForKey:@"aps"] valueForKey:@"alert"];

上面的代碼從推送信息中獲取了信息的內容。推送信息的JSON的格式看起來是這樣的:

{
	"aps":
	{
		"alert": "SENDER_NAME: MESSAGE_TEXT",
		"sound": "default"
	},
}

服務器把信息內容以及信息作者的暱稱放到了“alert”欄中。我們對這個字典中的其他內容並不感興趣。

	NSMutableArray* parts = [NSMutableArray arrayWithArray:[alertValue componentsSeparatedByString:@": "]];
	message.senderName = [parts objectAtIndex:0];
	[parts removeObjectAtIndex:0];
	message.text = [parts componentsJoinedByString:@": "];

上面的代碼將發送者的暱稱和信息內容分解出來放入到Message對象中。發送者暱稱是分號和空格之前的字符串。

	int index = [dataModel addMessage:message];

現在我們可以把這個Message對象加入到DataModel中了。

	if (updateUI)
		[self.chatViewController didSaveMessage:message atIndex:index];

最後,我們讓ChatViewController加入這個新的信息。但是,如果推送信息是在didFinishLaunchingWithOptions函數中收到的,那我們就不能刷新這個視圖,因爲那時ChatViewController的表格還沒有加載。視圖加入這個信息會導致系統崩潰的。

就這些了。編譯並運行現有的程序。用test_message.html中的表格來發送一些信息。你應該在app的聊天視圖中看到這些信息氣泡出現。

自定義提示信息

你應該還記得我們之前在介紹推送信息時曾說過你可以自定義提示設置。比如你可以在有信息時播放一個自定義的提示音。我在app的resources文件夾中放了一個音頻文件叫做beep.caf。

打開api.php文件並在makePayload()函數中將下面這行代碼:

$payload = '{"aps":{"alert":"' . $nameJson . ': ' . $textJson . '","sound":"default"}}';

改爲

$payload = '{"aps":{"alert":"' . $nameJson . ': ' . $textJson . '","sound":"beep.caf"}}';


你不需要改變app本身的任何代碼,甚至不用重新編譯。但你還是應該在設備上關閉打開了的app。因爲如果我們的app正在前臺運行,那提示音是不會響的。現在用test_message.html給app發一個信息。當提示窗口出現時,提示音是不是不同了?

你也可以實驗修改其他的選項。比如提供自定義按鈕,或者給app設定數量小圖標。(如果你想實驗數量小圖標,別忘了讓app註冊接收數量圖標。現在我們的app只會有提示音和提示窗口。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章