本篇文章主要是整理一下有关通知的相关知识。主要介绍: 本地通知 远程通知 本文参考: 编写push notification之获取device token 编写push notification之服务器端发送通知 ios实现本地通知 ios实现本地通知 本地通知 本地通知,local notification,用于基
本篇文章主要是整理一下有关通知的相关知识。主要介绍:
本地通知远程通知本文参考:
编写push notification之获取device token编写push notification之服务器端发送通知ios实现本地通知ios实现本地通知本地通知本地通知,local notification,用于基于时间行为的通知,比如有关日历或者todo列表的小应用。另外,应用如果在后台执行,ios允许它在受限的时间内运行,它也会发现本地通知有用。比如,一个应用,在后台运行,向应用的服务器端获取消息,当消息到达时,比如下载更新版本的提示消息,通过本地通知机制通知用户。
本地通知是uilocalnotification的实例,主要有三类属性:
scheduled time,时间周期,用来指定ios系统发送通知的日期和时间;notification type,通知类型,包括警告信息、动作按钮的标题、应用图标上的badge(数字标记)和播放的声音;自定义数据,本地通知可以包含一个dictionary类型的本地数据。对本地通知的数量限制,ios最多允许最近本地通知数量是64个,超过限制的本地通知将被ios忽略。
如果就写个简单的定时提醒,是很简单的,比如这样:
示例写的很简单,启动应用后,就发出一个定时通知,10秒后启动。这时按home键退出,一会儿就会提示上图的提示信息。如果应用不退出则无效。
代码如下:
uilocalnotification *notification=[[uilocalnotification alloc] init];
if (notification!=nil) {
nslog(@>> support local notification);
nsdate *now=[nsdate new];
notification.firedate=[now addtimeinterval:10];
notification.timezone=[nstimezone defaulttimezone];
notification.alertbody=@该去吃晚饭了!;
[[uiapplication sharedapplication] schedulelocalnotification:notification];
更详细的代码见官方文档:《scheduling, registering, and handling notifications》,可以设置比如声音,比如用户定义数据等。
设置更多本地通知的信息:
设置icon上数字。- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions {
// override point for customization after application launch.
/////////////
application.applicationiconbadgenumber = 0;
// add the view controller’s view to the window and display.
[self.window addsubview:viewcontroller.view];
[self.window makekeyandvisible];
return yes;
}
添加通知时间,通知类型,取消通知#pragma mark –
#pragma mark onchagevalue
-(ibaction)onchangevalue:(id)sender
{
uiswitch *switch1=(uiswitch *)sender;
if (switch1.on) {
uilocalnotification *notification=[[uilocalnotification alloc] init];
nsdate *now1=[nsdate date];
notification.timezone=[nstimezone defaulttimezone];
notification.repeatinterval=nsdaycalendarunit;
notification.applicationiconbadgenumber = 1;
notification.alertaction = nslocalizedstring(@显示, nil);
switch (switch1.tag) {
case 0:
{
notification.firedate=[now1 datebyaddingtimeinterval:10];
notification.alertbody=self.mylable1.text;
}
break;
case 1:
{
notification.firedate=[now1 datebyaddingtimeinterval:20];
notification.alertbody=self.mylable2.text;
}
break;
case 2:
{
notification.firedate=[now1 datebyaddingtimeinterval:30];
notification.alertbody=self.mylable3.text;
}
break;
default:
break;
}
[notification setsoundname:uilocalnotificationdefaultsoundname];
nsdictionary *dict = [nsdictionary dictionarywithobjectsandkeys:
[nsstring stringwithformat:@%d,switch1.tag], @key1, nil];
[notification setuserinfo:dict];
[[uiapplication sharedapplication] schedulelocalnotification:notification];
}else {
nsarray *myarray=[[uiapplication sharedapplication] scheduledlocalnotifications];
for (int i=0; i uilocalnotification *myuilocalnotification=[myarray objectatindex:i];
if ([[[myuilocalnotification userinfo] objectforkey:@key1] intvalue]==switch1.tag) {
[[uiapplication sharedapplication] cancellocalnotification:myuilocalnotification];
}
}
}
}
远程通知远程通知的原理:《偷窥iphone push notification的幕后》和《iphone的push(推送通知)功能原理浅析》。
设备的准备首先要知道,push notification只能在真机上运行的,无法在模拟器上使用,如果在模拟器上运行,在注册设备的时候会有类似如下报错:
error in registration. error: error domain=nscocoaerrordomain code=3010 remote notifications are not supported in the simulator userinfo=0x5d249d0 {nslocalizeddescription=remote notifications are not supported in the simulator}
真机也要注意,如果没有越狱,没有问题。越狱的话,比如通过blacksnow,因为没有经过itunes,无法生成有效的设备证书(device certificate),因此注册的时候不会成功。
检查越狱版本是否可用,可以ssh到设备上,执行命令:
ls /var/mobile/library/preferences/com.apple.apsd.plist -l
-rw——- 1 mobile mobile 119 aug 24 19:21 /var/mobile/library/preferences/com.apple.apsd.plist
返回的文件大小是119,就没有问题。
2.获取device token的原理
在说操作步骤之前,先说一下获取device token的一些原理方面的事情。
device token,即设备令牌,不是系统唯一标识(见获取ios设备的基本信息),需要在应用启动时发起到apple服务器请求,注册自己的设备和应用,并获得这个device token。
device token有什么用?如果应用需要push notification给手机,那么它要有个服务器端(provider),但是它发出的信息不是直接给手机的,而是必须统一交给apple的服务器,这个服务器就是apple push notification server(apns)。apple服务器通过这个token,知道应用要发的消息是给哪个手机设备的,并转发该消息给手机,手机再通知应用程序。
3.获取device token的操作步骤
这里主要参照了这篇文章:programming apple push notification services
该文档很详细,照做就应该没有问题。
需要注意的是identifier一定要和provision portal profile中的app id一致,即:
要和:
一致。
另外,要确保设备绑定的是唯一的profile:
编写代码,是在appdelegate中增加两个方法:
didregisterforremotenotificationswithdevicetoken:当应用第一次运行的时候,ios获取到device token后调用,用于注册设备到apns上之后的操作(比如将device token通知应用的服务器端provider)didfailtoregisterforremotenotificationswitherror:如果注册的时候失败,ios会调用这个方法,可以打印一些报错日志或者提醒用户通知不可用另外,有一个方法需要增加内容,主要是打印日志,说明是否已经注册:
- (void)applicationdidfinishlaunching:(uiapplication *)application {
[[uiapplication sharedapplication] setapplicationiconbadgenumber:0];
nslog(@initiating remotenoticationssareactive);
if(!application.enabledremotenotificationtypes){
nslog(@initiating remotenoticationssareactive1);
[[uiapplication sharedapplication] registerforremotenotificationtypes:(uiremotenotificationtypealert | uiremotenotificationtypesound | uiremotenotificationtypebadge)];
}
uiapplication* myapp = [uiapplication sharedapplication];
myapp.idletimerdisabled = yes;
[window addsubview:viewcontroller.view];
[window makekeyandvisible];
}
第一次运行带注册方法的应用,会看到类似这样的提示窗口:
然后,在日志中看到类似下面的日志,主要是看到打印出device token的64位字符串,就说明成功了。
5.获得证书苹果提供两种接入方式的证书:
developer,用于测试production,用于产品如果是内部测试,使用developer方式即可。
下载证书,通过ios provisioning portal:
这要求:
登录的apple developer program帐号必须是级别最高的agent(这是针对企业帐号来说的,如果是个人帐号就无所谓了),agent帐号即创始帐号,否则看不到configure链接;必须经过configure操作,已经enable了developer和product。然后进入configure链接,点击download按钮即可:
6.处理证书如果是编写在mac下跑的objc程序,无需对证书做处理,可跳过这一步。
如果是在java下使用,需要把打证书用的私有专用密钥和上述的支持通知的证书(注意,不是iphone developer证书)合并导出。
生成证书:
点击存储的时候,会提示生成一个文件密码:
当然可以密码为空。
之后会提示:
这里需要输入mac登录用户的密码。
文件生成。
7.编写发送通知的实例如果是编写mac代码,有一个现成的项目可用:http://stefan.hafeneger.name/download/pushmebabysource.zip
导入到xcode中,只需将:
devicetoken填写成设备的token字符串,另外,pathforresource改为上面图中的:
aps_developer_identity
另外,要把刚才获得证书步骤中下载的证书复制到xcode项目resources目录下:
可以看到文件名和上面的pathforresource的参数一致。
之后运行程序就可以在设备上收到推送通知。
如果是用java编写,可以用第三方库,见:
http://code.google.com/p/javapns/
编写简单的发送通知代码:
import org.json.jsonexception;
import javapns.back.pushnotificationmanager;
import javapns.back.sslconnectionhelper;
import javapns.data.device;
import javapns.data.payload;
public class main {
/**
* @param args
* @throws exception
*/
public static void main(string[] args) throws exception {
payload simplepayload = new payload();
// get pushnotification instance
pushnotificationmanager pushmanager = pushnotificationmanager.getinstance();
// link iphone’s udid (64-char device token) to a stringname
pushmanager.adddevice(iphone, 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 );
simplepayload.addalert(my alert message测试);
simplepayload.addbadge(1);
simplepayload.addsound(default);
device client = pushnotificationmanager.getinstance().getdevice(iphone);
pushnotificationmanager.getinstance().initializeconnection(gateway.sandbox.push.apple.com, 2195, /home/ubuntu/mypush.p12, password, sslconnectionhelper.keystore_type_pkcs12);
pushnotificationmanager.getinstance().sendnotification(client, simplepayload);
测试中文没有乱码问题。
编写比较复杂的使用示例(可以控制通知是否有提示窗口、是否有提醒声音):
apayload.addbadge( 2),显示在手机应用图标上的数字apayload.addalert(软件版本有更新),显示提示窗口文字apayload.addsound(default.wav),指定提示声音另外,也可以使用php的第三方实现,比如:
http://code.google.com/p/php-apns
基本原理是启动一个php服务,监控memcacheq队列,如果有消息就发送给苹果服务器。
from:http://wangjun.easymorse.com/?p=1482
