很早在自己的一款项目也做过推送,并且是由自己生成证书等流程。这部分内容网上大都有,这里不多做细说。
自己目前的项目这次也需要做一个推送,点击推送后到达一个目标界面。
当然,推送使用的是第三方的sdk,网上的第三方sdk一大堆,随便摘几个来用就好,这里就不帮他们做广告了。
略过一大堆,直接开始说配置完成的操作。
创建推送管理类,负责推送的初始化、注册、开始、停止、上传到服务器,保存内容等操作。
<span style="color:#999999;">#import <Foundation/Foundation.h>
@interface PushHelper : NSObject
#pragma mark -
#pragma mark 单例
/*!
* 创建推送管理类
*
* @return 推送管理类
*/
+ (instancetype)sharedPushHelper;
#pragma mark -
#pragma mark 注册
/*!
* 推送注册
*/
- (void)registerRemoteNotification;
/*!
* 开始个推
*/
- (void)beginGexinSdk;
/*!
* 结束个推
*/
- (void)endGexinSdk;
/*!
* 注册设备号
*
* @param deviceToken 设备号
*/
- (void)registerDeviceToken:(NSString *)deviceToken;
#pragma mark -
#pragma mark 界面
/*!
* 存储推送过来的内容
*/
@property (nonatomic, strong) NSString *bodyContent;
@end</span>
具体实现不详细写,列出几个重点。
<span style="color:#999999;">#pragma mark -
#pragma mark 单例
/*!
* 获取推送管理类单例
*
* @return 推送管理类
*/
+ (instancetype)sharedPushHelper {
static PushHelper* sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[super allocWithZone:NULL] init];
});
return sharedInstance;
}
#pragma mark -
#pragma mark 推送注册
/*!
* 注册apns
*/
- (void)registerRemoteNotification {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
UIUserNotificationSettings *uns = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:uns];
} else {
#endif
UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge);
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
}
#endif
}
</span>
<span style="color:#999999;">#pragma mark -
#pragma mark GexinSdkDelegate
/*!
* 个推注册返回
*
* @param clientId 客户端id
*/
- (void)GexinSdkDidRegisterClient:(NSString *)clientId {
NSLog(@"clientId %@", clientId);
_sdkStatus = SdkStatusStarted;
self.clientId = clientId;
[self uploadClientId];
}
/*!
* 收到个推消息
*
* @param payloadId 推送消息id
* @param appId 应用id
*/
- (void)GexinSdkDidReceivePayload:(NSString *)payloadId fromApplication:(NSString *)appId {
NSLog(@"payloadId %@ appId %@", payloadId, appId);
NSData *payload = [_gexinPusher retrivePayloadById:payloadId];
NSString *payloadMsg = nil;
if (payload) {
payloadMsg = [[NSString alloc] initWithBytes:payload.bytes
length:payload.length
encoding:NSUTF8StringEncoding];
NSLog(@"payloadMsg %@", payloadMsg);
id obj = [NSJSONSerialization JSONObject:payloadMsg];
if ([obj isKindOfClass:[NSDictionary class]]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"InfoRemoteNotification" object:nil userInfo:obj];
}
}
}
/*!
* 发送上行消息结果反馈
*
* @param messageId 消息id
* @param result 上传结果
*/
- (void)GexinSdkDidSendMessage:(NSString *)messageId result:(int)result {
NSLog(@"Received sendmessage:%@ result:%d", messageId, result);
}
/*!
* 个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。
*
* @param error 错误详情
*/
- (void)GexinSdkDidOccurError:(NSError *)error {
NSLog(@">>>[GexinSdk error]:%@", [error localizedDescription]);
}
</span>
为使用做准备,之后操作基本都是在AppDelegate
说明:当一个应用程序成功的注册一个推送服务(APS)
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"deviceToken:%@", token);
[[PushHelper sharedPushHelper] registerDeviceToken:token];//注册token
}
说明: 当
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Failed to get token, error:%@", error);
[[PushHelper sharedPushHelper] registerDeviceToken:@""];
}
说明: 当一个运行着的应用程序收到一个远程的通知
<span style="color:#c0c0c0;">- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"userInfo %@", userInfo);
[[PushHelper sharedPushHelper] setBodyContent:userInfo]; //设置内容到自身,看你们怎么设置了
}</span>
//成功注册registerUserNotificationSettings:后,回调的方法
//该方法为iOS8之后的方法 可以command+点击该方法进入。
<span style="color:#c0c0c0;">#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[application registerForRemoteNotifications];
}
#endif</span>
程序在启动时候会调用该方法,一般情况下,launchOptions为nil。
假如我们程序没有加载,这时候我们突然接收到一条消息,点击推送这时候并不会进入
<span style="color:#c0c0c0;">- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo</span>
该方法,而是进入didFinishLaunchingWithOptions这个方法,而这时候,launchOptions并不会为空,并且有launchOptions字典中存储者userInfo的资料,我们只需要将其取出。
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
下面这些方法,也是很有作用的一些方法,可以作为参考,如果App有其他特殊的需要。
- -(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler
- {
- //在没有启动本App时,收到服务器推送消息,下拉消息会有快捷回复的按钮,点击按钮后调用的方法,根据identifier来判断点击的哪个按钮
- }
- -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
- {
- //收到本地推送消息后调用的方法
- NSLog(@"%@",notification);
- }
- -(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
- {
- //在非本App界面时收到本地消息,下拉消息会有快捷回复的按钮,点击按钮后调用的方法,根据identifier来判断点击的哪个按钮,notification为消息内容
- NSLog(@"%@----%@",identifier,notification);
- completionHandler();//处理完消息,最后一定要调用这个代码块
- }