使用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.
return
YES;
}
- (
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;
// ...
return
true
;
}
public
override
void
RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
// 成功接收到用于消息推送的token
string
tokenStr = token.Description;
string
pushToken = tokenStr.Replace(
"<"
,
string
.Empty).Replace(
">"
,
string
.Empty).Replace(
" "
,
string
.Empty);
NSUserDefaults.StandardUserDefaults.SetString(pushToken,
"pushtoken"
);
}
public
override
void
FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
// 消息推送注册失败
}
public
override
void
DidReceiveRemoteNotification(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.Samples及PushSharp.Client目录。
服务端推送消息
1
2
3
4
5
6
7
8
9
|
var
pusher =
new
PushBroker();
pusher.RegisterAppleService(
new
ApplePushChannelSettings(File.ReadAllBytes(
"yourAppId.p12"
),
"证书的密码"
));
pusher.QueueNotification(
new
AppleNotification()
.ForDeviceToken(pushToken)
// 从数据库等地方获取设备的pushToken
.WithAlert(
"测试iOS消息推送 - 囧月"
)
.WithBadge(1)
.WithSound(
"default"
)
);
|
在RegisterAppleService方法中可以注册多个APNS证书,PushSharp可以自动检测是Development/Production,这时候需要为证书设置标识:
1
2
|
pusher.RegisterAppleService(
new
ApplePushChannelSettings(File.ReadAllBytes(
"yourAppId.p12"
),
"证书的密码"
),
"证书标识如youAppId_development"
);
pusher.RegisterAppleService(
new
ApplePushChannelSettings(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;
static
void
pusher_OnNotificationFailed(
object
sender, INotification notification, Exception error)
{
var
n = (AppleNotification)notification;
//error.Message ...获取推送出错的信息
}
static
void
pusher_OnNotificationSent(
object
sender, INotification notification)
{
//消息推送成功后
var
n = (AppleNotification)notification;
//n.Payload.Alert.Body 获取推送的消息内容...
}
static
void
pusher_OnDeviceSubscriptionExpired(
object
sender,
string
expiredSubscriptionId, DateTime expirationDateUtc, INotification notification)
{
// 从数据库删除过期的expiredSubscriptionId
}
static
void
pusher_OnDeviceSubscriptionChanged(
object
sender,
string
oldSubscriptionId,
string
newSubscriptionId, INotification notification)
{
// 把数据库中的oldSubscriptionId更新为newSubscriptionId
}
|
更多请参考源码的PushSharp.Sample目录。
参考
官方网站:https://github.com/Redth/PushSharp 可以获取最新源码及各种例子
WIKI:https://github.com/Redth/PushSharp/wiki 详细说明了各平台证书配置的方法
作者:囧月
出处:http://lwme.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
#1楼 walleyekneel 2013-12-14 15:44
#2楼[楼主] 囧月 2013-12-14 16:48
没有测试过繁体中文..
#3楼 小鸡哥 2013-12-14 20:54
#4楼 cry 2013-12-14 21:38
#5楼 6572789 2013-12-15 13:44
#6楼 银河使者 2013-12-15 21:55
#7楼 deerchao 2013-12-15 22:58
#8楼 sunlovesea 2013-12-16 08:32
#9楼 llllboy 2013-12-16 08:59
#10楼 城岸 2013-12-16 09:05
#11楼 上帝的病人 2013-12-16 09:10
#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了
#13楼 城岸 2013-12-16 09:21
#14楼[楼主] 囧月 2013-12-16 10:05
有在这些事件里记录日志了么?是Apple的服务器那边的问题还是什么问题?
@城岸
新的功能还退化了?..跟作者反馈一下看看
#15楼 euler 2013-12-16 10:34
#16楼 银河使者 2013-12-24 22:31
PhoneGap可以调用Android Java API