PushSharp如何向APNS发送消息

来源:互联网 发布:知乎 童话书 编辑:程序博客网 时间:2024/06/05 15:00
Spiga
  • Posts - 65, Articles - 0, Comments - 207
  • Cnblogs
  • Dashboard
  • Login

使用PushSharp给iOS应用推送消息

2013-12-14 11:21 by 囧月, 1435 阅读, 16 评论, 收藏, 编辑

PushSharp是一个C#编写的服务端类库,用于推送消息到各种客户端,支持iOS(iPhone/iPad)、Android、Windows Phone、Windows 8、Amazo、Blackberry等设备。

官方网站:https://github.com/Redth/PushSharp

当前最新稳定版本为2.0.4,支持通过NuGet获取(https://www.nuget.org/packages/PushSharp/)

 

主要特点

提供了易于使用的API,支持以下平台的消息推送:

  • Apple (APNS – iPhone, iPad, OSX 10.8+):APNS即Apple Push Notification Service,详见:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
  • Android (GCM/C2DM - 手机及平板):GCM即Google Cloud Message,详见:http://developer.android.com/google/gcm/index.html
  • Chrome (GCM)
  • Amazon (ADM):ADM即Amazon Device Messaging,详见:https://developer.amazon.com/sdk/adm/setup.html
  • Windows Phone 7/7.5/8(包括FlipTile,CycleTile及IconicTile模板):详见:http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff402558(v=vs.105).aspx
  • Windows 8
  • Blackberry (BIS and BES via PAP): 详见:http://docs.blackberry.com/en/developers/deliverables/51382/
  • Firefox OS (即将支持)

100%的托管代码完全兼容Mono平台。

 

安装

PushSharp主要包含以下程序集:

  • PushSharp.Core:(必选)核心组件
  • PushSharp.Apple:APNS,用于iOS及OSX
  • PushSharp.Android:C2DM及GCM,用于Android设备
  • PushSharp.Windows:用于Windows 8
  • PushSharp.WindowsPhone:用于WP设备
  • PushSharp.Amazon.Adm:用于Amazon的设备
  • PushSharp.Blackberry:用于黑莓设备
  • PushSharp.Google.Chrome:用于Chrome

其中,PushSharp.Core为必须的组件,其他的可以根据自己需要来选择对应平台。

平常使用只需要用NuGet来获取程序集即可:

1
Install-Package PushSharp

这样会把主流平台的程序集(Apple/Android/Windows/WindowsPhone)都下载下来,可以根据自己需要删除用不到的平台组件。

假如需要使用Blackberry等NuGet包里没有的组件,则需要到官方网站(https://github.com/Redth/PushSharp)获取源码自行编译。

对于Apple平台,只需要PushSharp.Core和PushSharp.Apple组件即可。

 

证书配置

官方WIKI提供了详细的证书配置步骤:

  • Apple平台的证书配置:https://github.com/Redth/PushSharp/wiki/How-to-Configure-&-Send-Apple-Push-Notifications-using-PushSharp
  • Android平台的证书配置(使用GCM情况下):https://github.com/Redth/PushSharp/wiki/How-to-Configure-&-Send-GCM-Google-Cloud-Messaging-Push-Notifications-using-PushSharp

 

Apple平台证书创建流程:

  • 创建AppID
  • 为AppID配置用于APP签名的证书:分别有开发环境(Development)和生产环境(Production)的证书
  • 编辑AppID启用消息推送
  • 为AppID创建用于消息推送(APNS)的证书(包括Development和Production)
  • 下载以上证书并安装到Key Chain(钥匙串)
  • 导出用于消息推送(APNS)的证书为.p12格式,并为它设置密码:用于在服务端推送消息

 

对于Apple平台需要特别说明:

  • Provisioning Protal现在已经变成了Certificates, Identifiers & Profiles,可以从Member Center点进去或者iOS Developer Center找到
  • 对于已经发布的APP要启用消息推送功能,需要在Identifiers – App IDs找到对应的ID创建好APNS证书之后,再重新生成用于APP签名的证书,否则用于注册消息推送的代码(RegisterForRemoteNotificationTypes)不会正常工作,即返回的deviceToken为null
  • 在使用Development证书调试应用程序时服务端需要使用Development APNS证书来推送消息,使用Production证书发布到AppStore后推送消息需要使用Production APNS证书来推送消息

 

客户端启用消息推送

启用消息推送都是在AppDelegate里注册来完成的。

对于使用objc语言编写的客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if(application.enabledRemoteNotificationTypes == UIRemoteNotificationTypeNone)
    {
        [application registerForRemoteNotificationTypes:
         UIRemoteNotificationTypeAlert |
         UIRemoteNotificationTypeBadge |
         UIRemoteNotificationTypeSound];
    }
    application.applicationIconBadgeNumber = -1;
    // Override point for customization after application launch.
    returnYES;
}
 
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSString *pushToken = [[[[deviceToken description]
                             stringByReplacingOccurrencesOfString:@"<"withString:@""]
                            stringByReplacingOccurrencesOfString:@">"withString:@""]
                           stringByReplacingOccurrencesOfString: @" "withString: @""];
    [[NSUserDefaults standardUserDefaults] setObject:pushToken forKey:@"pushtoken"];// 保存起来
}

对于使用MonoTouch的客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    app.RegisterForRemoteNotificationTypes(
        UIRemoteNotificationType.Alert |
        UIRemoteNotificationType.Badge |
        UIRemoteNotificationType.Sound);
    app.ApplicationIconBadgeNumber = -1;
    // ...
    returntrue;
}
 
publicoverride voidRegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    // 成功接收到用于消息推送的token
    stringtokenStr = token.Description;
    stringpushToken = tokenStr.Replace("<",string.Empty).Replace(">",string.Empty).Replace(" ",string.Empty);
    NSUserDefaults.StandardUserDefaults.SetString(pushToken,"pushtoken");
}
 
publicoverride voidFailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
    // 消息推送注册失败
}
 
publicoverride voidDidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
    // 接收到推送的消息
    // 在iOS7可能需要开启Background Modes的Remote Notifications
}

在接收到deviceToken的时候先存储在NSUserDefaults中,在用户登录的时候再取出来一起发送到服务端:

1
2
NSString *pushToken = [[NSUserDefaults standardUserDefaults] stringForKey:@"pushtoken"];//objc
string pushToken = NSUserDefaults.StandardUserDefaults.StringForKey("pushtoken");//MonoTouch

服务端在用户登录成功之后,把接收到用户的用户名与pushToken关联起来,在推送消息的时候就可以针对指定用户来推送,具体的过程略。

而对于不需要用户登录的app,可以在接收到deviceToken的时候直接发送到服务端。

更多的客户端配置参考PushSharp源码的Client.SamplesPushSharp.Client目录。

 

服务端推送消息

1
2
3
4
5
6
7
8
9
var pusher = new PushBroker();
pusher.RegisterAppleService(newApplePushChannelSettings(File.ReadAllBytes("yourAppId.p12"),"证书的密码"));
pusher.QueueNotification(
                newAppleNotification()
                    .ForDeviceToken(pushToken)// 从数据库等地方获取设备的pushToken
                    .WithAlert("测试iOS消息推送 - 囧月")
                    .WithBadge(1)
                    .WithSound("default")
            );

在RegisterAppleService方法中可以注册多个APNS证书,PushSharp可以自动检测是Development/Production,这时候需要为证书设置标识:

1
2
pusher.RegisterAppleService(newApplePushChannelSettings(File.ReadAllBytes("yourAppId.p12"),"证书的密码"), "证书标识如youAppId_development");
pusher.RegisterAppleService(newApplePushChannelSettings(File.ReadAllBytes("yourAppId.p12"),"证书的密码"), "证书标识如youAppId_production");

此外,可以注册各种事件来获得各种状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
pusher.OnDeviceSubscriptionChanged += pusher_OnDeviceSubscriptionChanged;
pusher.OnDeviceSubscriptionExpired += pusher_OnDeviceSubscriptionExpired;
pusher.OnNotificationSent += pusher_OnNotificationSent;
pusher.OnNotificationFailed += pusher_OnNotificationFailed;
pusher.OnNotificationRequeue += pusher_OnNotificationRequeue;
pusher.OnChannelCreated += pusher_OnChannelCreated;
pusher.OnChannelDestroyed += pusher_OnChannelDestroyed;
pusher.OnChannelException += pusher_OnChannelException;
pusher.OnServiceException += pusher_OnServiceException;
 
staticvoid pusher_OnNotificationFailed(objectsender, INotification notification, Exception error)
{
    varn = (AppleNotification)notification;
    //error.Message ...获取推送出错的信息
}
 
staticvoid pusher_OnNotificationSent(objectsender, INotification notification)
{
    //消息推送成功后
    varn = (AppleNotification)notification;
    //n.Payload.Alert.Body  获取推送的消息内容...
}
 
staticvoid pusher_OnDeviceSubscriptionExpired(objectsender, stringexpiredSubscriptionId, DateTime expirationDateUtc, INotification notification)
{
    // 从数据库删除过期的expiredSubscriptionId
}
 
staticvoid pusher_OnDeviceSubscriptionChanged(objectsender, stringoldSubscriptionId, stringnewSubscriptionId, INotification notification)
{
    // 把数据库中的oldSubscriptionId更新为newSubscriptionId
}

更多请参考源码的PushSharp.Sample目录。

 

参考

官方网站:https://github.com/Redth/PushSharp 可以获取最新源码及各种例子

WIKI:https://github.com/Redth/PushSharp/wiki  详细说明了各平台证书配置的方法

Xamarin相关文档:http://docs.xamarin.com/guides/cross-platform/application_fundamentals/notifications/ios/remote_notifications_in_ios/ 

作者:囧月
出处:http://lwme.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类: .NET, 移动开发
标签: ios, monotouch,PushSharp
绿色通道:好文要顶关注我收藏该文与我联系
囧月
关注 - 55
粉丝 - 93
+加关注
7
0
(请您对文章做出评价)
«上一篇:使用MonoTouch.Dialog简化iOS界面开发
Add your comment
  1. #1楼walleyekneel   2013-12-14 15:44
    楼主有没有试过繁体发送是乱码
    支持(0)反对(0)
  2. #2楼[楼主]囧月   2013-12-14 16:48
    @walleyekneel
    没有测试过繁体中文..
    支持(0)反对(0)
  3. #3楼小鸡哥   2013-12-14 20:54
    这个牛叉
    支持(0)反对(0)
  4. #4楼cry   2013-12-14 21:38
    mark
    支持(0)反对(0)
  5. #5楼6572789   2013-12-15 13:44
    不错,收藏了
    支持(0)反对(0)
  6. #6楼银河使者   2013-12-15 21:55
    这个在Mono上测试过吗,可以在Linux或Mac OS X上运行吗
    支持(0)反对(0)
  7. #7楼deerchao   2013-12-15 22:58
    请教下,用这个方案的话,对Android设备在国内实际效果如何(会不会被伟大的墙干扰造成不稳定)?
    支持(0)反对(0)
  8. #8楼sunlovesea   2013-12-16 08:32
    牛!!!!!是否支持PhoneGap这类打包的WebAPP呢?
    支持(0)反对(0)
  9. #9楼llllboy   2013-12-16 08:59
    MARK
    支持(0)反对(0)
  10. #10楼城岸   2013-12-16 09:05
    多线程下不知道什么原因会一起卡在那里(Win8下不会),无法解决,只好放弃它了,用回APNS-sharp.
    支持(0)反对(0)
  11. #11楼上帝的病人   2013-12-16 09:10
    不太稳定, 有时候能收到通知,有时候不能
    支持(0)反对(0)
  12. #12楼[楼主]囧月   2013-12-16 09:19
    @银河使者
    这个不用怀疑Mono的能力
    @deerchao
    Android用Google的服务在国内稳定性估计很差,国内有不少的厂商提供的替代方案像“百度云推送”之类的可靠性比较好
    @sunlovesea
    支持,这个只是服务端的库,客户端用什么框架没影响的,可以参考这个:http://devgirl.org/2013/07/17/tutorial-implement-push-notifications-in-your-phonegap-application/
    @城岸
    APNS-Sharp和PushSharp是同一个作者啊,而且APNS-Sharp早已经obsolete/deprecated了
    支持(0)反对(0)
  13. #13楼城岸   2013-12-16 09:21
    嗯,我就是先使用APNS-Sharp,后想升级到PushSharp。
    支持(0)反对(0)
  14. #14楼[楼主]囧月   2013-12-16 10:05
    @上帝的病人
    有在这些事件里记录日志了么?是Apple的服务器那边的问题还是什么问题?
    @城岸
    新的功能还退化了?..跟作者反馈一下看看
    支持(0)反对(0)
  15. #15楼euler   2013-12-16 10:34
    Great API!
    支持(0)反对(0)
  16. #16楼银河使者   2013-12-24 22:31
    @sunlovesea
    PhoneGap可以调用Android Java API
    支持(0)反对(0)
刷新评论刷新页面返回顶部
游戏开发者的福利:阿里云云服务器免费送
最新IT新闻:
· 辞掉你的工作,去开发一个应用:我的创业故事
· 刘军VS雷军 未来5年中国最瞩目的对决
· 广东北京移动4G套餐对比:套餐起步价128元
· iPhone让Android重新设计?别闹了
· 芬兰语言学家:iPhone的拼写实际上错了
» 更多新闻...
最新知识库文章:
· 浅析深究什么是中间件
· 思考、学习新技术的原则和方式
· 云风:一个编程的自由人
· 多研究些问题,少谈些主义
· 领域建模中的七种坏味道信息
» 更多知识库文章...
0 0